﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Aspects;
using System.Reflection;

namespace EBookStore.AOP
{
    
 
    [Serializable] 
    public class NotNullOrConcreteObjectAttribute:OnMethodBoundaryAspect
    {

        public int Index { get; set; }
        public Type BaseType { get; set; }
        public Type ConcreteType { get; set; }
        public string Message { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public NotNullOrConcreteObjectAttribute()
        {
            Index = -1;
            BaseType = null;
            ConcreteType = null;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        public override void OnEntry(MethodExecutionArgs args)
        {
            Arguments a = args.Arguments;            
            ParameterInfo[] pis = args.Method.GetParameters();

            if (Index >= 0 && BaseType != null)
            {
                if (pis[Index].ParameterType == BaseType && a[Index] == null)
                {
                    if (ConcreteType != null && (a[Index].GetType() != ConcreteType))
                    {
                        throw new Exception(
                            string.Format("Concrete type doesn't match expected\nExpected:{0} Recieved:{1}",
                            ConcreteType.FullName,
                            a[Index].GetType().FullName));
                    }
                    if (Message.Length > 0)
                    {
                        throw new Exception(Message);
                    }
                    else
                    {
                        throw new Exception(string.Format("Object '{0}'  is null", BaseType.Name));
                    }
                    
                }
            }
                                              
        }
        
    }


}
